package game.classes.gameField;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

import game.classes.interfaces.Area;
import game.classes.interfaces.Block;
import game.classes.interfaces.Tile;
import game.enums.BlockID;
import game.enums.Direction;
import game.enums.FloorID;
import game.enums.MaterialID;
public class gameArea implements Area, Serializable {

	private static final long serialVersionUID = 1L;
	Block[][] BlockList;
	Tile[][] TileList;
	
	public gameArea() {
	}
	
	public gameArea(int maxX, int maxY) {
		BlockList = new Block[maxX][maxY];
		TileList = new Tile[maxX][maxY];
		
		for (int i = 0; i < maxX; i++) {
			for (int j = 0; j < maxY; j++) {
				BlockList[i][j] = new gameBlock(i, j, BlockID.NONE, BlockList);
				TileList[i][j] = new gameTile(i, j, FloorID.NONE, TileList);
			}
		}
	}
	
	public gameArea(Block[][] BlockBuffer,Tile[][] TileBuffer) {
		BlockList=BlockBuffer;
		TileList=TileBuffer;
	}
	
	public void loadLevelFromFile(String dataName)
	{
		gameArea buffer = new gameArea();
	      try
	      {
	    	  // Mapnamen auflösen zum Laden
	         FileInputStream fileIn = new FileInputStream("resource/level/"+dataName+".map");
	         ObjectInputStream in = new ObjectInputStream(fileIn);
	         buffer = (gameArea) in.readObject();
	         in.close();
	         fileIn.close();
	      }catch(IOException i)
	      {
	         i.printStackTrace();
	         return;
	      }catch(ClassNotFoundException c)
	      {
	         c.printStackTrace();
	         return;
	      }
	      for(int i=0;i<20;i++)
			{
				for(int j=0;j<20;j++)
				{
					BlockList = buffer.BlockList.clone();
					TileList = buffer.TileList.clone();
				}
			}
	      buffer = null;
	}
	
	@Override
	public int getMaxX() {
		return BlockList.length;
	}

	@Override
	public int getMaxY() {
		return BlockList[0].length;
	}

	@Override
	public Tile getTileAtPos(int x, int y) {
		return TileList[x][y];
	}

	@Override
	public void setTileAtPos(int x, int y, FloorID id) {
		TileList[x][y].setID(id);
	}

	@Override
	public Block getBlockAtPos(int x, int y) {
		return BlockList[x][y];
	}

	@Override
	public void setBlockAtPos(int x, int y, BlockID id) {
		if (id == BlockID.BLOCK || id == BlockID.WALL) {
			return;
		}
		Block buffer = new gameMovable(x, y, id, BlockList);
		BlockList[x][y] = buffer;
	}
	
	public void setBlockAtPos(int x, int y, BlockID bid, MaterialID mid) {
		if (bid != BlockID.BLOCK && bid != BlockID.WALL) {
			setBlockAtPos(x, y, bid);
			return;
		}
		Block buffer = new gameMovable(x, y, bid, mid, BlockList);
		BlockList[x][y] = buffer;
	}

	@Override
	public boolean moveBlock(int x, int y, Direction dir) {
		Block buffer = null;
		if (y >= 0 && y <= BlockList[0].length - 1 && x <= BlockList.length - 1 && x >= 0) {
			buffer = BlockList[x][y];
		}
		if (buffer != null) {
			if (buffer.getBlockID() == BlockID.BLOCK) {
				switch (dir) {
				case UP: {
					if (y > 0) {
						if (BlockList[x][y-1].getBlockID() != BlockID.BLOCK && BlockList[x][y-1].getBlockID() != BlockID.WALL) {
							BlockList[x][y] = BlockList[x][y-1];
							BlockList[x][y-1] = buffer;
							return true;
						}
					}
					break;
				}
				case DOWN: {
					if (y < BlockList[0].length - 1) {
						if (BlockList[x][y+1].getBlockID() != BlockID.BLOCK && BlockList[x][y+1].getBlockID() != BlockID.WALL) {
							BlockList[x][y] = BlockList[x][y+1];
							BlockList[x][y+1] = buffer;
							return true;
						}
					}
					break;
				}
				case RIGHT: {
					if (x < BlockList.length - 1) {
						if (BlockList[x+1][y].getBlockID() != BlockID.BLOCK && BlockList[x+1][y].getBlockID() != BlockID.WALL) {
							BlockList[x][y] = BlockList[x+1][y];
							BlockList[x+1][y] = buffer;
							return true;
						}
					}
					break;
				}
				case LEFT: {
					if (x > 0) {
						if (BlockList[x-1][y].getBlockID() != BlockID.BLOCK && BlockList[x-1][y].getBlockID() != BlockID.WALL) {
							BlockList[x][y] = BlockList[x-1][y];
							BlockList[x-1][y] = buffer;
							return true;
						}
					}
					break;
				}
				default:
				}
			}
		}
		return false;
	}

}
